package com.example.tutorialwebsocket.service;

import com.alibaba.fastjson.JSONObject;
import com.example.tutorialwebsocket.vo.NotifyVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: cph
 * @date: 2023/10/20 16:03
 */
@Slf4j
@Component
@ServerEndpoint("/notice/{userId}")
public class WebSocketNotifyService {

    public static Map<String, Session> clients = new ConcurrentHashMap<>();
    public static Map<String, Set<String>> conns = new ConcurrentHashMap<>();
    private String sid = null;
    private String userId;


    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.sid = UUID.randomUUID().toString();
        this.userId = userId;
        clients.put(sid, session);

        Set<String> clientSet = conns.get(userId);
        if (Objects.isNull(clientSet)) {
            clientSet = new HashSet<>();
            conns.put(userId, clientSet);
        }
        clientSet.add(this.sid);
        log.info("连接开启,sid:{}", this.sid);
    }

    @OnClose
    public void onClose() {
        log.info("连接断开,sid:{}", this.sid);
        clients.remove(this.sid);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到{}的消息:{}", this.sid, message);
    }

    @OnError
    public void onError(Throwable e) {
        log.error("发生未知错误");
        e.printStackTrace();
    }


    public static boolean isClose() {
        if (clients.size() == 0) {
            return true;
        } else {
            return false;
        }
    }

    public static void sendMessage(String noticeType) {
        NotifyVO resp = new NotifyVO();
        resp.setNotifyType(noticeType);
        sendMessage(resp);
    }

    public static void sendMessage(NotifyVO resp) {
        String message = JSONObject.toJSONString(resp);
        for (Session session : clients.values()) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                log.error("发送消息异常");
            }
        }
    }

    public static void sendMessageByUserId(String userId, NotifyVO resp) {
        if (StringUtils.hasText(userId)) {
            String message = JSONObject.toJSONString(resp);
            Set<String> clientSet = conns.get(userId);
            if (Objects.nonNull(clientSet)) {
                Iterator<String> iterator = clientSet.iterator();
                while (iterator.hasNext()) {
                    String sid = iterator.next();
                    Session session = clients.get(sid);
                    if (Objects.nonNull(session)) {
                        try {
                            session.getBasicRemote().sendText(message);
                        } catch (Exception e) {
                            log.error("发送消息异常");
                        }
                    }
                }
            }
        }
    }

}
